use m3u8_dl::{m3u8_env::HistoryArgs, utils};
use owo_colors::OwoColorize;

use std::{
    fs::{self, DirEntry},
    path::Path,
};

#[tokio::main]
async fn main() {
    let args = HistoryArgs::from_cli().await;

    let ts_dir_path = args.dir_path_str.clone();
    let ts_dir = Path::new(&ts_dir_path);
    let name = args.name.clone();
    let m3u8_url = args.m3u8_url.clone();
    let batch_size = args.batch_size;

    let pt_msg = format!(
        r#"
    -> 下载任务: {name} 
    -> m3u8 url: {m3u8_url}
    -> 并发下载数: {batch_size}
    -> 临时文件保存地址: {ts_dir_path}
            "#
    );
    println!("{}", pt_msg.yellow());

    loop {
        let count = download(&args).await;
        if count == 0 {
            break;
        }
        eprintln!("{}个TS文件下载失败", count);
    }

    // 生成list文件
    let input_path = utils::generate_list_file(ts_dir.clone());

    // 根据list文件生成mp4
    // ffmpeg -f concat -safe 0 -i fileList.txt -c copy mergedVideo.mp4
    let _out_dir = ts_dir.parent().unwrap().join(format!("{name}.mp4"));
    let output_path = _out_dir.into_os_string().into_string().unwrap();
    let _status = utils::merge_video(&input_path, &output_path);

    // 清理TS文件
    // if _status.success() {
    //     fs::remove_dir_all(ts_dir_path).unwrap();
    // }
}

async fn download(args: &HistoryArgs) -> usize {
    let ts_dir_path = args.dir_path_str.clone();
    let ts_dir = Path::new(&ts_dir_path);
    let key = args.key.clone().unwrap();
    let batch_size = args.batch_size;

    let ts_count = args.ts_url_list.clone().map_or(0, |l| l.len());

    let ts_url_list = args
        .ts_url_list
        .clone()
        .unwrap()
        .iter()
        .enumerate()
        .filter(|item| {
            let ts_name = format!("{}.ts", item.0);
            let ts_file_path = ts_dir.join(ts_name);
            return !ts_file_path.exists();
        })
        .map(|item| {
            let item_0 = item.0 as u32;
            let item_1 = item.1.to_string();
            (item_0, item_1.clone())
        })
        .collect::<Vec<_>>();

    if let Err(err) = m3u8_dl::m3u8_dl(ts_dir, ts_url_list, key, batch_size).await {
        panic!("{}:{:?}", "下载失败".red(), err);
    }

    // 检查是否所有同时文件都下载OK
    let dir_reader = std::fs::read_dir(ts_dir).unwrap();
    let dl_ts_count = dir_reader
        .filter(|_entry| {
            let Ok(_entry) = _entry else { return false; };

            let file_name = _entry.file_name();
            let file_name = file_name.to_str().unwrap_or("");

            file_name.ends_with(".ts")
        })
        .count();

    ts_count - dl_ts_count
}
